from hjl_spider.download.base import DownloadBase
import requests
from json import loads
from lxml import etree


class HttpResponse(object):
    '''
    响应体类
    '''

    def __init__(self, url, text, move, status_code, content):
        '''
        http的响应类
        :param url:
        :param text: 文本
        :param move: 转移目标函数
        :param status_code: 状态码
        '''
        self.url = url
        self.text = text
        self.move = move
        self.status_code = status_code
        self.content = content

    @property
    def json_data(self) -> dict:
        '''
        json的load
        :return: dict
        '''
        return loads(self.text)

    def xpath(self, xpath_str):
        '''
        xpath解析
        :param xpath_str: xpath语法
        :return: xpath对象
        '''
        xls = etree.HTML(self.text)
        return xls.xpath(xpath_str)

    def re(self):
        pass

    def __str__(self):
        return "HttpResponse(url={}, status_code={}, move={})".format(self.url, self.status_code, self.move)


class HttpRequest(DownloadBase):
    '''
    Http类型的请求下载器
    '''

    def __init__(self, url=None, method=None, move='parse', params=None, data=None, **kwargs):
        '''
        初始化
        :param method: 请求类型
        :param params: 请求头部信息
        :param re_body: 请求体
        :param data: 发送数据
        :param move: 移动函数
        '''
        self.data = data
        self.url = url
        self.move = move
        self.kwargs = kwargs
        if not (method is None):
            self.method = method.upper()
        if not (params is None):
            self.params = params

        setting = self.kwargs.get("setting")

        self.timeout = setting.get("TIMEOUT", None)
        self.headers = setting.get("SPIDER_HEADERS", None)
        self.again = setting.get("AGAIN_DOWNLOAD", None)

    def __str__(self):
        '''
        查看类
        :return: str：类的基本属性
        '''

        return "HttpRequest(url={}, method={}, params={}, re_body{}, data{})".format(self.url,
                                                                                     self.method,
                                                                                     self.params,
                                                                                     self.re_body,
                                                                                     self.data)

    def download(self) -> HttpResponse:
        '''
        下载器下载方法
        :return: HttpResponse
        '''

        headers = self.kwargs.get("SPIDER_HEADERS", None)
        timeout = self.kwargs.get("TIMEOUT", None)

        if self.method == "GET":
            response = requests.get(self.url, params=self.params, timeout=self.timeout, headers=self.headers)

        elif self.method == "POST":
            response = requests.post(self.url, data=self.data, headers=self.headers, timeout=self.timeout)

        else:
            raise Exception("这不是一个合法的请求")

        if not response.status_code == 200:
            if self.again > 0:
                self.again -= 1  # 减少下载次数
                self.download()

            else:
                return None

        return HttpResponse(url=self.url, text=response.text, move=self.move,
                            status_code=response.status_code, content=response.content)
